-
Notifications
You must be signed in to change notification settings - Fork 13k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Run-make test to check core::ffi::c_*
types against clang
#133944
base: master
Are you sure you want to change the base?
Conversation
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @tgross35 (or someone else) some time within the next two weeks. Please see the contribution instructions for more information. Namely, in order to ensure the minimum review times lag, PR authors and assigned reviewers should ensure that the review label (
|
("c_char", "__CHAR_BIT__"), // Character width | ||
("char_signedness", "__CHAR_UNSIGNED__"), | ||
("c_double", "__SIZEOF_DOUBLE__"), // Double precision floating-point | ||
("c_float", "__SIZEOF_FLOAT__"), // Single precision floating-point | ||
("c_int", "__SIZEOF_INT__"), // Signed integer | ||
("c_long", "__SIZEOF_LONG__"), // Signed long integer | ||
("c_longlong", "__SIZEOF_LONG_LONG__"), // Signed long long integer | ||
("c_schar", "__SIZEOF_CHAR__"), // Signed char | ||
("c_short", "__SIZEOF_SHORT__"), // Signed short integer | ||
("c_uchar", "__SIZEOF_CHAR__"), // Unsigned char | ||
("c_uint", "__SIZEOF_INT__"), // Unsigned integer | ||
("c_ulong", "__SIZEOF_LONG__"), // Unsigned long integer | ||
("c_ulonglong", "__SIZEOF_LONG_LONG__"), // Unsigned long long integer | ||
("c_ushort", "__SIZEOF_SHORT__"), // Unsigned short integer | ||
("c_size_t", "__SIZEOF_SIZE_T__"), // Size type | ||
("c_ptrdiff_t", "__SIZEOF_PTRDIFF_T__"), // Pointer difference type]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should either prefer the standard macros of CHAR_WIDTH
and so on where available (which will be in bits instead of bytes, but eh, just hit it with >> 3
), or simply use the actual sizeof
operator within the generated C code.
This comment has been minimized.
This comment has been minimized.
try a program like this:
(and so on for the other types.) From there you can parse them into a map like you have for LLVM. to get a list of the available types you could use something like
|
Oh hey, thanks for working on this! There are two interesting bits here:
What I mentioned in #133058 (comment) works, I was able to prototype this out relatively easily. Solution to #1Rust has the internal // smallcore.rs (within this run-make directory)
#![allow(internal_features)]
#![feature(decl_macro)]
#![feature(intrinsics)]
#![feature(lang_items)]
#![feature(link_cfg)]
#![feature(no_core)]
#![feature(rustc_attrs)]
#![no_core]
#![no_std]
// This is in `tests/auxiliary/minicore.rs`
extern crate minicore;
use minicore::Sized;
// Copy the body from https://github.com/rust-lang/rust/blob/df5b8e39b7def660696340b199ae395a869b3064/library/core/src/internal_macros.rs#L149
macro_rules! cfg_if { /* ... */ }
macro_rules! panic {
($msg:literal) => { $crate::panic(&$msg) };
}
/* Intrinsics are function signatures that `rustc` does something magic with.
* The body doesn't matter. */
#[rustc_intrinsic]
#[rustc_intrinsic_const_stable_indirect]
#[rustc_intrinsic_must_be_overridden]
pub const fn size_of<T>() -> usize {
loop {}
}
#[rustc_intrinsic]
#[rustc_intrinsic_must_be_overridden]
pub const fn abort() -> ! {
loop {}
}
/* Lang items are similar to intrinsics but aren't limited to function signatures */
// This is what `panic!()` usually eventually expands to
#[lang = "panic"]
#[rustc_const_panic_str]
const fn panic(_expr: &&'static str) -> ! {
abort();
}
/* We need to reimplement some basic traits so rustc knows what to do with `==` and `!` */
#[lang = "eq"]
pub trait PartialEq<Rhs: ?Sized = Self> {
fn eq(&self, other: &Rhs) -> bool;
fn ne(&self, other: &Rhs) -> bool {
!self.eq(other)
}
}
#[lang = "not"]
pub trait Not {
type Output;
fn not(self) -> Self::Output;
}
impl PartialEq for usize {
fn eq(&self, other: &usize) -> bool {
(*self) == (*other)
}
}
impl Not for bool {
type Output = bool;
fn not(self) -> Self {
!self
}
} (@jieyouxu any interest in just putting some of this in minicore?) Solution to #2We can't build # Start with core/src/ffi copied to a temporary directory
# Remove stability attrbutes since they can't be used outside of std
perl -i -0777 -pe 's/#!?\[(un)?stable.*?\]//gs' ffi/mod.rs
# Remove doc attributes since we'll be removing some items they apply to
perl -i -0777 -pe 's/#\[doc.*?\]//gs' ffi/mod.rs
# Remove lang item indicators so they don't conflict if `minicore` gets updated
perl -i -0777 -pe 's/#\[lang.*?\]//gs' ffi/mod.rs
# Remove non-inline modules since we don't need `cstr` or `va_list`
perl -i -0777 -pe 's/.*mod.*;//g' ffi/mod.rs
# Remove reexports that go with those modules
perl -i -0777 -pe 's/.*use.*;//g' ffi/mod.rs
# Remove the `Debug` implementation for `c_void`. This is done in two steps
# to avoid regex tripping over `{`/`}`
perl -i -0777 -pe 's/fn fmt.*?\{.*?\}//gs' ffi/mod.rs
perl -i -0777 -pe 's/impl fmt::Debug for.*?\{.*?\}//gs' ffi/mod.rs
# Just for sanity sake when looking at the generated files, eliminate repeated empty lines
perl -i -0777 -pe 's/\n{3,}/\n\n/gs' ffi/mod.rs What might actually be better is to move the types we care about into a new TestsWrite a test file that asserts each size at compile time, using what we have in // tests.rs
use super::*; // `super` will include everything from `smallcore` once glued together
pub const TEST_C_CHAR_SIZE: () = if size_of::<ffi::c_char>() != CLANG_C_CHAR_SIZE {
panic!("wrong c_char size");
};
pub const TEST_C_LONG_SIZE: () = if size_of::<ffi::c_long>() != CLANG_C_LONG_SIZE {
panic!("wrong c_long size");
}; GlueThis is the only target-specific part: each target needs to generate its own file where you fill in the /* boilerplate part */
#![allow(unused)]
// include! rather than `mod` with `path` since this one has crate-level
// attributes
include!("path/to/smallcore.rs");
// Path to the simplified FFI file
#[path = "path/to/ffi.rs"]
mod ffi;
#[path = "path/to/tests.rs"]
mod tests;
/* end boilerplate */
/* Per-target: append to the template based on Clang's output */
const CLANG_C_CHAR_SIZE: usize = 1;
const CLANG_C_LONG_SIZE: usize = 8;
// ... Then just have rustc build the file for the relevant target; if our sizes are wrong, we'll get a failure at const eval. You can even pass |
I'll take a look later today, thanks for the detailed writeup. |
For checking the sign, you could do add something like this to trait Signed {
const SIGNED: bool;
}
impl Signed for i8 {
const SIGNED: bool = true;
}
impl Signed for u8 {
const SIGNED: bool = false;
}
const TEST_C_CHAR_SIGNED: () = if ffi::c_char::SIGNED ^ CLANG_C_CHAR_SIGNED {
panic("mismatched c_char sign");
}; This requires adding a |
Thanks! This is less nice than having core available ofc, but this builds a Most fragile thing is probably the text processing of |
One other thought: this PR shouldn't fix anything that doesn't currently line up, so there should be xfails. It might be easiest to just do this in // tests that always pass don't need a cfg_if
cfg_if! {
if #[cfg(target_os = "foobar")] {
// FIXME: long isn't long enough on foobar
const XFAIL_C_LONG_SIZE: usize = 16;
pub const TEST_C_LONG_SIZE: () = if size_of::<ffi::c_long>() != XFAIL_C_LONG_SIZE {
panic("wrong c_long size");
};
} else {
// Default test
pub const TEST_C_LONG_SIZE: () = if size_of::<ffi::c_long>() != CLANG_C_LONG_SIZE {
panic("wrong c_long size");
};
}
} |
Thanks for the write up, I appreciate it! Will read it and look to understand it tonight :). Just a quick question that might be off topic but I created the following function for testing purposes:
I wanted to save the sizes for the c types for the current target but I get 3 errors for the following types: c_ptrdiff_t The error is as follows: use of unstable library feature The open issue is issue #88345 My concern is that in the tests we are using size_of::ffi::TYPE(). If we input the type as c_size_t or the other 2 we will get an error. Should this effect the run-make test at all or is it fine? Edit: I am assuming adding #![feature(c_size_t)] allows the run-make test not to be affected by this. |
disregard this commit, gonna be following what you outlined for the solution. |
This comment has been minimized.
This comment has been minimized.
I was eepy yesterday, going to revisit this in a moment today. I'll need to revisit what the test requirements are. |
Just for reference, this would be correct if importing from |
Yes, if these items are only in core (not alloc, not std-only), please do add them to
Moving to
I don't actually know what |
@tgross35 |
@tgross35
this is how I attempt to build it but I receive this error: error[E0463]: can't find crate for I have tried to fix this problem through defining #![no_std] in the target file but that does not seem right and does not work. Smallcore is still the same as what you outlined and I created a mod.rs file like you explained. |
This comment has been minimized.
This comment has been minimized.
That file also needs Also as @jieyouxu mentioned above, you can add whatever is missing to |
@bors try |
Run-make test to check `core::ffi::c_*` types against clang Hello, I have been working on issue rust-lang#133058 for a bit of time now and would love some feedback as I seem to be stuck and not sure if I am approaching this correctly. I currently have the following setup: 1. Get the rust target list 2. Use rust target to query the llvm target 3. Get clang definitions through querying the clang command with llvm target. I only save the necessary defines. Here is an example of the saved info (code can easily be modified to store Width as well): Target: riscv64-unknown-linux-musl __CHAR_BIT__ = 8 __CHAR_UNSIGNED__ = 1 __SIZEOF_DOUBLE__ = 8 __SIZEOF_INT__ = 4 __SIZEOF_LONG__ = 8 __SIZEOF_PTRDIFF_T__ = 8 __SIZEOF_SIZE_T__ = 8 __SIZEOF_FLOAT__ = 4 __SIZEOF_LONG_LONG__ = 8 __SIZEOF_SHORT__ = 2 Target: riscv64-unknown-fuchsia __CHAR_UNSIGNED__ = 1 __SIZEOF_SHORT__ = 2 __CHAR_BIT__ = 8 __SIZEOF_INT__ = 4 __SIZEOF_SIZE_T__ = 8 __SIZEOF_FLOAT__ = 4 __SIZEOF_LONG__ = 8 __SIZEOF_DOUBLE__ = 8 __SIZEOF_PTRDIFF_T__ = 8 __SIZEOF_LONG_LONG__ = 8 - I then save this into a hash map with the following format: <LLVM TARGET, <DEFINE NAME, DEFINE VALUE>> - Ex: <x86_64-unknown-linux-gnu, <__SIZEOF_INT__, 4>> This is where it gets a bit shaky as I have been brainstorming ways to get the available c types in core::ffi to verify the size of the defined types but do not think I have the expertise to do this. For the current implementation I specifically focus on the c_char type (unsigned vs signed). The test is currently failing as there are type mismatches which are expected (issue rust-lang#129945 highlights this). I just do not know how to continue executing tests even with the type mismatches as it creates an error when running the run-make test. Or maybe I am doing something wrong in generating the test? Not too sure but would love your input. Thanks r? `@tgross35` `@jieyouxu` try-job: x86_64-gnu-debug
💔 Test failed - checks-actions |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Looks like #132570 might fix this discrepancy by using the proper UEFI targets instead of similar windows targets. |
@bors try |
Run-make test to check `core::ffi::c_*` types against clang Hello, I have been working on issue rust-lang#133058 for a bit of time now and would love some feedback as I seem to be stuck and not sure if I am approaching this correctly. I currently have the following setup: 1. Get the rust target list 2. Use rust target to query the llvm target 3. Get clang definitions through querying the clang command with llvm target. I only save the necessary defines. Here is an example of the saved info (code can easily be modified to store Width as well): Target: riscv64-unknown-linux-musl __CHAR_BIT__ = 8 __CHAR_UNSIGNED__ = 1 __SIZEOF_DOUBLE__ = 8 __SIZEOF_INT__ = 4 __SIZEOF_LONG__ = 8 __SIZEOF_PTRDIFF_T__ = 8 __SIZEOF_SIZE_T__ = 8 __SIZEOF_FLOAT__ = 4 __SIZEOF_LONG_LONG__ = 8 __SIZEOF_SHORT__ = 2 Target: riscv64-unknown-fuchsia __CHAR_UNSIGNED__ = 1 __SIZEOF_SHORT__ = 2 __CHAR_BIT__ = 8 __SIZEOF_INT__ = 4 __SIZEOF_SIZE_T__ = 8 __SIZEOF_FLOAT__ = 4 __SIZEOF_LONG__ = 8 __SIZEOF_DOUBLE__ = 8 __SIZEOF_PTRDIFF_T__ = 8 __SIZEOF_LONG_LONG__ = 8 - I then save this into a hash map with the following format: <LLVM TARGET, <DEFINE NAME, DEFINE VALUE>> - Ex: <x86_64-unknown-linux-gnu, <__SIZEOF_INT__, 4>> This is where it gets a bit shaky as I have been brainstorming ways to get the available c types in core::ffi to verify the size of the defined types but do not think I have the expertise to do this. For the current implementation I specifically focus on the c_char type (unsigned vs signed). The test is currently failing as there are type mismatches which are expected (issue rust-lang#129945 highlights this). I just do not know how to continue executing tests even with the type mismatches as it creates an error when running the run-make test. Or maybe I am doing something wrong in generating the test? Not too sure but would love your input. Thanks r? `@tgross35` `@jieyouxu` try-job: x86_64-gnu-debug
☀️ Try build successful - checks-actions |
🎉 congrats! |
Couldn't have done it without you. Huge thank you for your support :) . |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Two minor comment requests, and squash please, but this looks great to me! Thank you for keeping at this for so long.
I'd like Jieyou to take a look as well as the rmake expert, which should happen in a few more days. And that gives enough time for the core::ffi
refactoring to happen first, if you're able to do that.
|
||
preprocess_core_ffi(); | ||
|
||
let targets_json = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let targets_json = | |
// Print the list of target JSON files, which will be used to match Rust target strings to LLVM | |
// target strings | |
let targets_json = |
const MAPPED_TARGETS: &[(&str, &str)] = &[ | ||
("armv5te-unknown-linux-uclibcgnueabi", "armv5te-unknown-linux"), | ||
("mips-unknown-linux-uclibc", "mips-unknown-linux"), | ||
("mipsel-unknown-linux-uclibc", "mips-unknown-linux"), | ||
("powerpc-unknown-linux-gnuspe", "powerpc-unknown-linux-gnu"), | ||
("powerpc-unknown-linux-muslspe", "powerpc-unknown-linux-musl"), | ||
("x86_64-unknown-l4re-uclibc", "x86_64-unknown-l4re"), | ||
]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are these targets where we have the wrong LLVM string and should fix that, or where LLVM is different from Clang? A note would be good.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The first val in the pair is a viable llvm target but it is not supported on clang. Hence I just map it to the "default" version that is supported on clang.
For reference:
❯ rustc -Z unstable-options --target=mipsel-unknown-linux-uclibc --print target-spec-json
{
"arch": "mips",
...
"llvm-target": "mipsel-unknown-linux-uclibc",
...
"os": "linux",
...
}
clang attempt to build:
clang: error: version 'uclibc' in target triple 'mipsel-unknown-linux-uclibc' is invalid
Compiler returned: 1
I remove 'uclibc' from the target and proceed to compile with clang.
A follow up on this is what should the non-working llvm target map to? Is it viable to assume I can map it to mips-unknown-linux?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is fine, the libc
used shouldn't change the primitive size. A comment mentioning that they work for LLVM but not for clang is sufficient 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggestion: indeed, please document why this mapping is needed (and what purpose it serves)
Yup gonna start working on this ASAP, I hope to be done with it before Jieyou takes a look at this.
Added what the PR should be for reference. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for working on this. I left some preliminary feedback (I'll do another pass after the core/ffi
changes).
/// Vendored from the 'cfg_if' crate | ||
|
||
macro_rules! cfg_if { | ||
// match if/else chains with a final `else` | ||
( | ||
$( | ||
if #[cfg( $i_meta:meta )] { $( $i_tokens:tt )* } | ||
) else+ | ||
else { $( $e_tokens:tt )* } | ||
) => { | ||
cfg_if! { | ||
@__items () ; | ||
$( | ||
(( $i_meta ) ( $( $i_tokens )* )) , | ||
)+ | ||
(() ( $( $e_tokens )* )) , | ||
} | ||
}; | ||
|
||
// Internal and recursive macro to emit all the items | ||
// | ||
// Collects all the previous cfgs in a list at the beginning, so they can be | ||
// negated. After the semicolon is all the remaining items. | ||
(@__items ( $( $_:meta , )* ) ; ) => {}; | ||
( | ||
@__items ( $( $no:meta , )* ) ; | ||
(( $( $yes:meta )? ) ( $( $tokens:tt )* )) , | ||
$( $rest:tt , )* | ||
) => { | ||
// Emit all items within one block, applying an appropriate #[cfg]. The | ||
// #[cfg] will require all `$yes` matchers specified and must also negate | ||
// all previous matchers. | ||
#[cfg(all( | ||
$( $yes , )? | ||
not(any( $( $no ),* )) | ||
))] | ||
cfg_if! { @__identity $( $tokens )* } | ||
|
||
// Recurse to emit all other items in `$rest`, and when we do so add all | ||
// our `$yes` matchers to the list of `$no` matchers as future emissions | ||
// will have to negate everything we just matched as well. | ||
cfg_if! { | ||
@__items ( $( $no , )* $( $yes , )? ) ; | ||
$( $rest , )* | ||
} | ||
}; | ||
|
||
// Internal macro to make __apply work out right for different match types, | ||
// because of how macros match/expand stuff. | ||
(@__identity $( $tokens:tt )* ) => { | ||
$( $tokens )* | ||
}; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Problem: this isn't actually a core
macro. If you want cfg_if
, can you actually just depend on cfg_if
-the-crate in src/tools/run-make-support
, then re-export cfg_if
via run-make-support
? A run-make
test will have access to run-make-support
. See how object
or regex
are re-exported in run-make-support
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh I see, you actually want cfg_if
for the test file. In that case, can you just put cfg_if
in the test file, and not in minicore.rs
?
#[lang = "panic"] | ||
#[rustc_const_panic_str] | ||
const fn panic(_expr: &&'static str) -> ! { | ||
abort(); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Problem [PANIC 1/2]: AFAICT, this signature is wrong (this signature has one layer of reference too many), because:
rust/library/core/src/panicking.rs
Lines 128 to 133 in c37fbd8
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)] | |
#[cfg_attr(feature = "panic_immediate_abort", inline)] | |
#[track_caller] | |
#[rustc_const_stable_indirect] // must follow stable const rules since it is exposed to stable | |
#[lang = "panic"] // used by lints and miri for panics | |
pub const fn panic(expr: &'static str) -> ! { |
#[macro_export] | ||
macro_rules! panic { | ||
($msg:literal) => { | ||
$crate::panic(&$msg) | ||
}; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Problem [PANIC 2/2]: ... which is why this has an extra &
on $msg
.
} | ||
|
||
#[lang = "panic"] | ||
#[rustc_const_panic_str] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Problem: I think we may need to apply #[inline]
/#[inline(never)]
/#[inline(always)]
and #[rustc_nounwind]
and match core
's usage, because that can influence codegen. Note that panic
inline attreibutes are gated behind the panic_immediate_abort
cfg, e.g.
impl PartialEq for usize { | ||
fn eq(&self, other: &usize) -> bool { | ||
(*self) == (*other) | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggestion: I think you could use a macro to construct these impl PartialEq
s so as long as the shape remains compatible since I think that's also what core
does.
// If this test fails because Rust adds a target that Clang does not support, this target should be | ||
// added to SKIPPED_TARGETS. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit (style):
// If this test fails because Rust adds a target that Clang does not support, this target should be | |
// added to SKIPPED_TARGETS. | |
// If this test fails because Rust adds a target that Clang does not support, this target should be | |
// added to `SKIPPED_TARGETS`. |
use run_make_support::{clang, regex, rfs, rustc, serde_json}; | ||
use serde_json::Value; | ||
|
||
// It is not possible to run the Rust test-suite on these targets. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggestion: could we elaborate why we can't run this test against these targets?
use run_make_support::{clang, regex, rfs, rustc, serde_json}; | ||
use serde_json::Value; | ||
|
||
// It is not possible to run the Rust test-suite on these targets. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Question: if someone wants to add a new Tier 3 target (bare-metal), do they have to update this test?
const MAPPED_TARGETS: &[(&str, &str)] = &[ | ||
("armv5te-unknown-linux-uclibcgnueabi", "armv5te-unknown-linux"), | ||
("mips-unknown-linux-uclibc", "mips-unknown-linux"), | ||
("mipsel-unknown-linux-uclibc", "mips-unknown-linux"), | ||
("powerpc-unknown-linux-gnuspe", "powerpc-unknown-linux-gnu"), | ||
("powerpc-unknown-linux-muslspe", "powerpc-unknown-linux-musl"), | ||
("x86_64-unknown-l4re-uclibc", "x86_64-unknown-l4re"), | ||
]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggestion: indeed, please document why this mapping is needed (and what purpose it serves)
// Cleanup | ||
rfs::remove_file("processed_mod.rs"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: not necessary, if a run-make test is successful and you only created temporary files under CWD, the whole directory will be cleaned up.
Hello,
I have been working on issue #133058 for a bit of time now and would love some feedback as I seem to be stuck and not sure if I am approaching this correctly.
I currently have the following setup:
Get the rust target list
Use rust target to query the llvm target
Get clang definitions through querying the clang command with llvm target. I only save the necessary defines. Here is an example of the saved info (code can easily be modified to store Width as well):
Target: riscv64-unknown-linux-musl
CHAR_BIT = 8
CHAR_UNSIGNED = 1
SIZEOF_DOUBLE = 8
SIZEOF_INT = 4
SIZEOF_LONG = 8
SIZEOF_PTRDIFF_T = 8
SIZEOF_SIZE_T = 8
SIZEOF_FLOAT = 4
SIZEOF_LONG_LONG = 8
SIZEOF_SHORT = 2
Target: riscv64-unknown-fuchsia
CHAR_UNSIGNED = 1
SIZEOF_SHORT = 2
CHAR_BIT = 8
SIZEOF_INT = 4
SIZEOF_SIZE_T = 8
SIZEOF_FLOAT = 4
SIZEOF_LONG = 8
SIZEOF_DOUBLE = 8
SIZEOF_PTRDIFF_T = 8
SIZEOF_LONG_LONG = 8
This is where it gets a bit shaky as I have been brainstorming ways to get the available c types in core::ffi to verify the size of the defined types but do not think I have the expertise to do this.
For the current implementation I specifically focus on the c_char type (unsigned vs signed). The test is currently failing as there are type mismatches which are expected (issue #129945 highlights this). I just do not know how to continue executing tests even with the type mismatches as it creates an error when running the run-make test. Or maybe I am doing something wrong in generating the test? Not too sure but would love your input. Thanks
r? @tgross35 @jieyouxu
try-job: x86_64-gnu-debug